from markupsafe import Markup

from odoo import fields, models, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT


class AccountMove(models.Model):
    _inherit = 'account.move'

    s_statement_start_date = fields.Date('Starting date of statement')
    s_statement_end_date = fields.Date('Ending date of statement')

    s_workflow_template_id = fields.Many2one(
        'sb.workflow.template', string="Approval Workflow Template",
        domain="[('sb_workflow_template_item_ids', '!=', False), ('workflow_type', '=', 'account_in')]")
    s_workflow_id = fields.Many2one('sb.workflow', string="Current Approval Workflow", copy=False)
    s_workflow_state = fields.Selection(related="s_workflow_id.state", store=True, readonly=True, string="Approval Status")
    # s_workflow_item_ids = fields.One2many(related="workflow_id.sb_workflow_item_ids", string="Approval Items")
    s_refuse_reason = fields.Text('refuse reason', copy=False)

    def action_approval(self):
        self.ensure_one()
        user = self.env.user
        workflow_item_ids = self.s_workflow_id.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval')
        for item in workflow_item_ids:
            if user in item.user_group_ids:
                item.approval_pass()
                break
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'type': 'success',
                'message': _('Approval successful'),
                'next': {'type': 'ir.actions.act_window_close'},
            }
        }

    def action_refuse(self):
        self.ensure_one()
        user = self.env.user
        if not self.s_refuse_reason:
            raise ValidationError(_('Please fill in the reason for rejection'))
        workflow_item_ids = self.s_workflow_id.sb_workflow_item_ids.filtered(lambda x: x.state == 'approval')
        for item in workflow_item_ids:
            if user in item.user_group_ids:
                item.refuse()
                break
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'type': 'success',
                'message': _('Approval refuse'),
                'next': {'type': 'ir.actions.act_window_close'},
            }
        }

    # def sb_button_confirm(self):
    #     return super().sb_button_confirm()

    def action_post(self):
        for rec in self:
            if rec.move_type in ('in_invoice', 'in_refund') and rec.s_workflow_state != 'approve':
                raise UserError(_('Approval not approved, unable to submit'))
        return super(AccountMove, self).action_post()

    @api.constrains('s_workflow_state')
    def constrains_s_workflow_state(self):
        for rec in self:
            if rec.s_workflow_state == 'approve':
                rec.action_post()

    def action_create_workflow(self):
        self.ensure_one()
        if not self.attachment_ids:
            raise UserError(_('Please upload a scanned copy of the stamped and signed supplier statement!'))
        if not self.s_workflow_template_id:
            raise ValidationError(_('Please select an approval template.'))
        # 创建审批流
        new_wf_id = self.env['sb.workflow'].sudo().create({
            'name': self.name + _('-Approval Flow'),
            'approval_time': fields.Datetime.now(),
            'workflow_type': self.s_workflow_template_id.workflow_type,
        })
        self.s_workflow_id = new_wf_id.id
        # 根据模板生成审批项
        item_audit_levels = []
        for item in self.s_workflow_template_id.sb_workflow_template_item_ids:
            new_item = self.env['sb.workflow.item'].sudo().create({
                'name': item.name,
                'user_group_ids': item.user_group_ids.ids,
                'audit_level': item.audit_level,
                'sb_workflow_id': new_wf_id.id,
                'state': 'wait_forward',
                'is_plan': item.is_plan
            })
            # 收集生成的审核项的所有层级
            item_audit_levels.append(new_item.audit_level)
        # 去重排序
        item_audit_levels = list(set(item_audit_levels))
        item_audit_levels.sort()
        # 开放最低层级的神匹配
        for n_item in new_wf_id.sb_workflow_item_ids:
            if n_item.audit_level == item_audit_levels[0]:
                n_item.state = 'approval'

    @api.model
    def amount_to_chinese(self, amount):
        """
        将金额转换为大写中文

        """
        # 数字对应的大写中文
        num_to_chinese = {
            '0': '零', '1': '壹', '2': '贰', '3': '叁', '4': '肆',
            '5': '伍', '6': '陆', '7': '柒', '8': '捌', '9': '玖'
        }

        # 单位
        units = ['', '拾', '佰', '仟']
        big_units = ['', '万', '亿']

        # 处理小数部分
        if isinstance(amount, float):
            amount_str = f"{amount:.2f}"
        else:
            amount_str = str(amount)

        if '.' in amount_str:
            integer_part, decimal_part = amount_str.split('.')
        else:
            integer_part, decimal_part = amount_str, ''

        # 去除整数部分的前导零
        integer_part = integer_part.lstrip('0') or '0'

        # 处理整数部分为0的情况
        if integer_part == '0':
            result = '零'
        else:
            result = ''
            # 按四位一组处理整数部分
            integer_reversed = integer_part[::-1]  # 反转字符串便于按万进制分组
            groups = [integer_reversed[i:i + 4] for i in range(0, len(integer_reversed), 4)]

            for i, group in enumerate(groups):
                group_chinese = ''
                group = group[::-1]  # 恢复正常顺序

                # 处理四位数中的每一位
                zero_flag = False
                for j, digit in enumerate(group):
                    if digit == '0':
                        zero_flag = True
                    else:
                        if zero_flag and group_chinese:  # 需要加零
                            group_chinese += '零'
                        group_chinese += num_to_chinese[digit] + units[len(group) - j - 1]
                        zero_flag = False

                # 添加万、亿等大单位
                if group_chinese:
                    if i > 0:
                        group_chinese += big_units[i]
                    result = group_chinese + result

        # 处理小数部分
        if decimal_part and decimal_part != '00':
            result += '元'
            # 处理角
            if len(decimal_part) > 0 and decimal_part[0] != '0':
                result += num_to_chinese[decimal_part[0]] + '角'
            # 处理分
            if len(decimal_part) > 1 and decimal_part[1] != '0':
                result += num_to_chinese[decimal_part[1]] + '分'
            else:
                result += '整'
        else:
            result += '元整'

        return result

    def _get_reason_for_payment(self):
        self.ensure_one()
        reason = ''
        if self.s_statement_start_date and self.s_statement_end_date:
            reason += f'{self.s_statement_start_date.strftime(DEFAULT_SERVER_DATE_FORMAT)} To {self.s_statement_end_date.strftime(DEFAULT_SERVER_DATE_FORMAT)} <br/>'
        reason += f'{self.invoice_payment_term_id.name} <br/>'
        categ_ids = self.line_ids.mapped('product_id.categ_id')
        for cate in categ_ids:
            reason += f'{cate.display_name} - {cate.en_name or ""} <br/>'
        return Markup(reason)